/*
 * TowerUpgradeRange.java
 *
 * Created on January 19, 2008, 11:57 AM
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package hextd.tower;

import hextd.hex.Hex;
import hextd.core.Context;
import hextd.core.ContextNormal;
import hextd.util.TowerListener;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.util.Iterator;
import java.util.ArrayList;

/**
 *
 * @author hylke
 */
public class TowerUpgradeRange extends TowerBase implements TowerListener {

	public static int price = 0;
	public static int damage = 0;
	public static float range = 4.3f;
	private ArrayList<Tower> clients;
	private Line2D[] clientLines;
	private Stroke clientStroke;
	private Color clientColor;
	public static float upgradeEffectRange = 0.5f;

	/** Creates a new instance of TowerUpgradeRange */
	public TowerUpgradeRange(Context context, Hex hex, int owner, int activateTick) {
		super(TowerFactory.type.upgradeRange, price, damage, range, owner, activateTick);

		hexInfluence = 1;
		this.lineColor = new Color(200, 200, 200);
		this.clientColor = new Color(50, 255, 50);
		this.clients = new ArrayList<Tower>();

		this.doInit(context, hex);
		this.pts = null;

		this.context.addTowerListener(this);
		this.scanTowers();
	}

	@Override
	protected boolean runActivate() {
		if (super.runActivate()) {
			scanTowers();
			return true;
		} else {
			return false;
		}
	}

	private void scanTowers() {
		if (!selling && active) {
			Tower t;
			float dx, dy;
			float[] loc;
			for (Iterator<Tower> i = context.getTowers().iterator(); i.hasNext();) {
				t = i.next();
				if (!this.clients.contains(t) && t.getOwner() == getOwner()) {
					loc = t.getHex().getFloatLocation();
					dx = this.xFloat - loc[0];
					dy = this.yFloat - loc[1];
					if ((dx * dx + dy * dy) < this.rangeCurrent2) {
						t.registerTower(this);
					}
				} else {
					loc = t.getHex().getFloatLocation();
					dx = this.xFloat - loc[0];
					dy = this.yFloat - loc[1];
					if (clients.contains(t) && (dx * dx + dy * dy) > this.rangeCurrent2) {
						t.unregisterTower(this);
					}
				}
			}
		}
	}

	@Override
	protected void calcDamageRange() {
		super.calcDamageRange();
		this.scanTowers();
	}

	@Override
	public boolean canUpgrade() {
		return false;
	}

	@Override
	public String getStatusString() {
		String retString = "";
		retString += "<h1>Range Upgrade</h1>" +
				"<p>" +
				"Increases the range of other towers, including other upgrade towers.<br>" +
				"<b>Towers affected:</b> " + this.clients.size() + "<br>\n" +
				"<b>Range:</b> " + this.rangeText + "<br>" +
				"</p>\n";
		return retString;
	}

	@Override
	public String getInfoString() {
		String retString = "";
		retString += "<h1>Range Upgrade</h1>" +
				"<p>Increases the range of other towers by " + upgradeEffectRange + ".</p>" +
				"<p class='warn'>This tower costs 1 bonus point.</p>";
		return retString;
	}

	@Override
	public void runTick(int gameTime) {
	}

	@Override
	public void towerBuild(Tower t) {
		if (t != this && !this.selling && !this.clients.contains(t) && t.getOwner() == getOwner()) {
			float dx, dy;
			float[] loc;
			loc = t.getHex().getFloatLocation();
			dx = this.xFloat - loc[0];
			dy = this.yFloat - loc[1];
			if ((dx * dx + dy * dy) < this.rangeCurrent2) {
				t.registerTower(this);
			}
		}
	}

	@Override
	public void towerRemoved(Tower t) {
		if (this.clients.contains(t)) {
			t.unregisterTower(this);
		}
	}

	public void addClient(Tower t) {
		if (!this.selling && !this.clients.contains(t)) {
			this.clients.add(t);
			this.generateShapes();
		}
	}

	public void removeClient(Tower t) {
		this.clients.remove(t);
		this.generateShapes();
	}

	@Override
	public void doCleanup() {
		super.doCleanup();
		for (int i = this.clients.size() - 1; i >= 0; i--) {
			Tower t = this.clients.get(i);
			t.unregisterTower(this);
		}
		this.context.removeTowerListener(this);
	}

	@Override
	public String getSvgName() {
		return "upgradeRange";
	}

	@Override
	protected void generateShapes() {
		if (context instanceof ContextNormal) {
			((ContextNormal) context).loadSvg("upgradeRange", "images/upgradeRange.svg");
		}
		float cx = +0;
		float cy = +0;

		this.shapes = new Shape[0];

		this.clientLines = new Line2D[this.clients.size()];
		float[] from;
		float[] to = this.getHex().getPaintLocation();
		to[0] += cx;
		to[1] += cy;
		for (int i = 0; i < this.clientLines.length; i++) {
			from = this.clients.get(i).getHex().getPaintLocation();
			this.clientLines[i] = new Line2D.Float(from[0], from[1], to[0], to[1]);
		}
		this.clientStroke = new BasicStroke(1.0f * strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
	}

	@Override
	public void paintEffects(Graphics2D g2, int gameTime) {
		if (selected) {
			g2.setStroke(this.clientStroke);
			g2.setColor(this.clientColor);
			for (int i = 0; i < this.clientLines.length; i++) {
				g2.draw(this.clientLines[i]);
			}
		}
	}
}
